package com.zyl.blog.tasks.aspect;

import com.zyl.blog.common.domain.task.bean.TaskAlert;
import com.zyl.blog.common.utils.Extreme.LogUtil;
import com.zyl.blog.tasks.mapper.TaskAlertMapper;
import com.zyl.blog.tasks.schedule.abstracts.AbstractScheduledTask;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog_Server
 * @Package: com.zyl.blog.tasks.aspect
 * @ClassName: TaskAlertAspect
 * @Description: 任务警告AOP切面，处理任务执行异常
 * @Author FinalFantasy
 * @Date 2025/8/12-15:59
 */
@Aspect
@Component
@RequiredArgsConstructor
public class TaskAlertAspect {

    private final TaskAlertMapper taskAlertMapper;

    /**
     * 异常通知，记录任务执行异常
     */
    @AfterThrowing(pointcut = "execution(* com.zyl.blog.tasks.schedule.abstracts.AbstractScheduledTask.execute(..)) && this(task)",
            throwing = "ex", argNames = "joinPoint,task,ex")
    public void handleTaskException(JoinPoint joinPoint, AbstractScheduledTask task, Exception ex) {
        TaskAlert alert = new TaskAlert();
        alert.setTaskName(task.getTaskName());
        alert.setUsername(task.getUsername());
        alert.setAlertTime(LocalDateTime.now());
        alert.setAlertLevel("ERROR");
        alert.setAlertMessage("任务执行异常: " + ex.getMessage());

        // 获取堆栈信息
        StringBuilder stackTrace = new StringBuilder();
        Arrays.stream(ex.getStackTrace())
                .limit(10) // 只记录前10行堆栈信息
                .forEach(element -> stackTrace.append(element.toString()).append("\n"));
        alert.setStackTrace(stackTrace.toString());

        taskAlertMapper.insert(alert);

        // 打印警告信息
        printAlertMessage(alert);
    }

    /**
     * 打印警告信息
     */
    private void printAlertMessage(TaskAlert alert) {
        String alertTemplate = """
                任务警告:
                - 警告级别: %s
                - 任务名称: %s
                - 所属用户: %s
                - 警告时间: %s
                - 警告信息: %s
                - 堆栈跟踪: %s
                """;
        Object[] args = {
                alert.getAlertLevel(),
                alert.getTaskName(),
                alert.getUsername(),
                alert.getAlertTime(),
                alert.getAlertMessage(),
                alert.getStackTrace()
        };

        LogUtil.error(alertTemplate, null, args);
    }
}
